const Article = require('../models/index/Article')
const Column = require('../models/index/Column')
const ArticleColumn = require('../models/index/ArticleColumn')
const columnService = require('./columnService.js')
const { Op } = require('sequelize')
const sequelize = require('../models/db')
const validate = require('validate.js')
const ViewsEcharts = require('../models/index/ViewsEcharts')
const moment = require('moment')

// 创建文章
exports.createArticle = async function (ArticleObj) {
  const ins = await Article.create(ArticleObj)
  if (!ArticleObj.dynamicColumn) {
    return ins
  }

  const dynamicColumn = ArticleObj.dynamicColumn
  const arr = []

  for (let i = 0; i < dynamicColumn.length; i++) {
    const column = await Column.findAll({
      where: {
        name: dynamicColumn[i]
      }
    })
    let columnId = undefined
    if (column.length == 0) {
      // 查询不到数据,创建一个专栏
      const result = await columnService.createColumn({ name: dynamicColumn[i] })
      columnId = result.id
    } else {
      columnId = column[0].id
    }

    arr.push({
      ArticleId: ins.id,
      ColumnId: columnId
    })
  }
  //   创建多个专栏关联
  await ArticleColumn.bulkCreate(arr)
  if (ins) {
    return ins
  }
  return null
}

// 更新文章
exports.updateArticle = async function (id, ArticleObj) {
  let ins = await Article.update(ArticleObj, {
    where: {
      id
    }
  })
  ins = JSON.parse(JSON.stringify(ins))

  // 没有这个文章，更新错误
  if (!ins[0]) {
    return null
  }

  if (!ArticleObj.dynamicColumn || ArticleObj.dynamicColumn.length <= 0) {
    return ArticleObj
  }
  let oldColumn = await ArticleColumn.findAll({
    where: {
      ArticleId: id
    }
  })
  oldColumn = JSON.parse(JSON.stringify(oldColumn))

  const dynamicColumn = ArticleObj.dynamicColumn
  let nowColumn = []

  for (let i = 0; i < dynamicColumn.length; i++) {
    let column = await Column.findOne({
      where: {
        name: dynamicColumn[i]
      }
    })
    column = JSON.parse(JSON.stringify(column))
    let columnId = undefined
    if (column.length == 0) {
      // 查询不到数据,创建一个专栏
      let result = await columnService.createColumn({ name: dynamicColumn[i] })
      result = result.toJSON()
      columnId = result.id
    } else {
      columnId = column.id
    }

    nowColumn.push({
      ArticleId: +id,
      ColumnId: +columnId
    })
  }

  for (let i = 0; i < nowColumn.length; i++) {
    let nowHave = await ArticleColumn.findOne({
      where: {
        ArticleId: nowColumn[i].ArticleId,
        ColumnId: nowColumn[i].ColumnId
      }
    })

    nowHave = JSON.parse(JSON.stringify(nowHave))

    if (!nowHave) {
      // 当没有这个关联时，创建这个关联。
      await ArticleColumn.create({ ArticleId: nowColumn[i].ArticleId, ColumnId: nowColumn[i].ColumnId })
    }
  }
  // 以前有关联，现在没有关联
  for (let i = 0; i < oldColumn.length; i++) {
    let nowHave = nowColumn.find((item) => item.ColumnId == oldColumn[i].ColumnId)
    if (!nowHave) {
      // 之前有这个关联，但是现在没有这个关联，需要删除这个关联
      await ArticleColumn.destroy({
        where: {
          ArticleId: oldColumn[i].ArticleId,
          ColumnId: oldColumn[i].ColumnId
        }
      })
    }
  }

  ArticleObj.id = +id

  return ArticleObj
}

// 获取文章列表
exports.getArticles = async function (offset, limit) {
  let list = await Article.findAndCountAll({
    order: [['createdAt', 'DESC']],
    offset,
    limit
  })
  list = JSON.parse(JSON.stringify(list))

  return { total: list.count, list: list.rows }
}

// 删除文章
exports.deleteArticle = async function (id) {
  const result = await Article.destroy({
    where: {
      id
    }
  })
  return result
}

// 用主键查询文章
exports.getArticleById = async function (id) {
  // 通过主键来查询一条记录
  const result = await Article.findByPk(id, {
    include: [Column]
  })
  if (result) {
    return JSON.parse(JSON.stringify(result))
  }
  return null
}

// 获取上一条文章
exports.getPreArticle = async function (id) {
  const result = await Article.findOne({
    where: {
      id: {
        [Op.lt]: id
      }
    }
  })
  if (result) {
    return JSON.parse(JSON.stringify(result))
  }
  return null
}

// 获取下一条文章
exports.getNextArticle = async function (id) {
  const result = await Article.findOne({
    where: {
      id: {
        [Op.gt]: id
      }
    }
  })
  if (result) {
    return JSON.parse(JSON.stringify(result))
  }
  return null
}

// 搜索文章
exports.getSearchResult = async function (page, limit, value = '', year, month, type) {
  let beginTime = undefined
  let endTime = undefined
  if (month) {
    // 月初到月末
    beginTime = new Date(+year, +month, 2)
    endTime = new Date(+year, +month + 1)
  } else if (!month && year) {
    beginTime = new Date(year)
    endTime = new Date((+year + 1).toString())
  }
  endTime = endTime ? endTime : new Date()
  beginTime = beginTime ? beginTime : new Date(1970)

  let result = await Article.findAndCountAll({
    attributes: ['id', 'title', 'img', 'description', 'createdAt', 'views', 'tabList'],
    include: [Column],
    where: {
      [Op.or]: [
        {
          title: {
            [Op.like]: `%${value}%`
          }
        }
        // {
        //   description: {
        //     [Op.like]: `%${value}%`
        //   }
        // }
      ],
      createdAt: {
        [Op.lt]: endTime,
        [Op.gt]: beginTime
      }
    },
    offset: (page - 1) * limit,
    limit: +limit
  })
  // 查个不分页的，因为一个文章属性同个专栏查出来是两条，但是结果是一条
  let all = await Article.findAndCountAll({
    attributes: ['id', 'title', 'img', 'description', 'createdAt', 'views'],
    include: [Column],
    where: {
      [Op.or]: [
        {
          title: {
            [Op.like]: `%${value}%`
          }
        },
        {
          description: {
            [Op.like]: `%${value}%`
          }
        }
      ],
      createdAt: {
        [Op.lt]: endTime,
        [Op.gt]: beginTime
      }
    }
  })
  if (result) {
    let list = JSON.parse(JSON.stringify(result.rows))
    if (type) {
      list = list.filter((item) => {
        for (let i = 0; i < item.Columns.length; i++) {
          return item.Columns[i].id === +type
        }
      })
    }

    return {
      total: JSON.parse(JSON.stringify(all)).rows.length,
      list: list
    }
  }
  return null
}

// 获取热门文章
exports.getHotArticles = async function (limit) {
  const count = await Article.count()
  const result = await Article.findAll({
    order: [['views', 'DESC']],
    limit: limit
  })
  if (result) {
    return { total: count, list: result }
  }
  return null
}

// 计算浏览量
exports.sendRecord = async function (id, obj) {
  // 根据id定位到文章，再将文章的浏览量 加上 1
  const result = await Article.increment({ views: 1 }, { where: { id: id } })
  // 浏览量加入表格，以 2022-01-10 的格式返回
  const timeName = formatDateTimeYMD(new Date())
  function formatDateTimeYMD(date) {
    const tem = new Date(date)
    var y = tem.getFullYear()
    var m = tem.getMonth() + 1
    m = m < 10 ? '0' + m : m
    var d = tem.getDate()
    d = d < 10 ? '0' + d : d
    return y + '-' + m + '-' + d
  }

  // 向浏览数表添加一项，属性名为2022-01-10，属性值为 1
  exports.createViewsEchart(timeName, 1)
  // 如果result有值就返回
  if (result) {
    return result
  }
  return null
}

// 获取所有文章的浏览量
exports.getAllRecord = async function () {
  // 查询所有文章的views属性
  let result = await Article.findAll({
    attributes: ['views']
  })
  // 转换为JSON数据
  result = JSON.parse(JSON.stringify(result))
  // 如果result有值，将所有的浏览量加起来
  if (result) {
    let count = 0
    for (let i = 0; i < result.length; i++) {
      // 统计所有浏览量
      count += result[i].views
    }
    return count
  }
  // 如果没有的话返回null
  return null
}

// 获取文章数量

exports.getArticleCount = async function () {
  let result = await Article.findAll()
  result = JSON.parse(JSON.stringify(result))
  if (result) {
    return result.length
  }
  return null
}

// 获取所有文章评论
exports.getCommentCount = async function () {
  return 0
}

exports.getArticleRelation = async function (id) {
  let columns = await Article.findByPk(id, {
    include: [Column]
  })
  columns = JSON.parse(JSON.stringify(columns)).Columns

  let result = []

  for (let i = 0; i < columns.length; i++) {
    let tem = await Column.findByPk(columns[i].id, {
      include: [Article]
    })
    tem = JSON.parse(JSON.stringify(tem)).Articles
    result.push(...tem)
    // 去重，不同专栏可能有相同的文章
  }

  let filter = []
  let exit = []
  for (let i = 0; i < result.length; i++) {
    if (exit.length === 0 && result[i].id != id) {
      exit.push(result[i].id)
      filter.push(result[i])
    } else {
      if (exit.indexOf(result[i].id) >= 0) {
        continue
      } else if (result[i].id != id) {
        exit.push(result[i].id)
        filter.push(result[i])
      }
    }
  }

  if (filter) {
    return filter
  }
  return null
}

exports.getViewsEchart = async function (limit = 7) {
  let result = await ViewsEcharts.findAll({
    where: {
      createdAt: {
        [Op.gt]: new Date(new Date() - limit * 24 * 60 * 60 * 1000)
      }
    }
  })
  result = JSON.parse(JSON.stringify(result))
  const obj = {}
  for (let i = 0; i < result.length; i++) {
    if (obj[result[i].timeName]) {
      obj[result[i].timeName]++
    } else {
      obj[result[i].timeName] = 1
    }
  }
  return obj
}

exports.createViewsEchart = async function (time, views) {
  return await ViewsEcharts.create({ timeName: time, views: views })
}

exports.updatedViewsEchart = async function (time, views, id) {
  return await ViewsEcharts.update(
    { timeName: time, views: views },
    {
      where: { id }
    }
  )
}

exports.getSearchOption = async function () {
  let result = await Article.findAll()
  result = JSON.parse(JSON.stringify(result))

  if (result) {
    return result
  }
  return null
}

exports.getMonth = async function (year) {
  // year传字符串才会识别为年份，不然会识别为数字
  let beginYear = new Date(year)
  let endYear = new Date((+year + 1).toString())
  let result = await Article.findAll({
    where: {
      createdAt: {
        [Op.lt]: endYear,
        [Op.gt]: beginYear
      }
    }
  })
  result = JSON.parse(JSON.stringify(result))

  if (result) {
    return result
  }
  return null
}
